package org.jetlinks.pro.notify.wechat.web;

import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Getter;
import lombok.Setter;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.authorization.annotation.QueryAction;
import org.hswebframework.web.authorization.annotation.Resource;
import org.jetlinks.pro.notify.wechat.WeixinGeneralRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.validation.constraints.NotNull;
import java.io.Serializable;

/**
 * @author gyl
 * @version 1.0
 * @time 2021/11/29 10:20
 */
@RestController
@RequestMapping("/notifier/wechat")
@Authorize
@Resource(id = "wechatMessage", name = "微信消息")
@Tag(name = "微信消息管理")
public class WeChatOffcialController {


    private static final WebClient webClient = WebClient.builder()
                                                        .build();

    private static final String infoApi = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template";
    private static final String tokenApi = "https://api.weixin.qq.com/cgi-bin/token";


    /**
     * 获取微信模板内容与标题
     *
     * @return
     */
    @GetMapping("/template/info")
    @QueryAction
    @Operation(summary = "获取微信模板消息内容和标题")
    public Mono<WechatTempalateDataInfo> getWechatTemplateData(@RequestBody WechatTempalateDataRequest request) {
        return requestToken(webClient, request.getAppId(), request.getSecret())
            .flatMap(token -> WeixinGeneralRequest
                .sendGet(webClient,
                         UriComponentsBuilder
                             .fromUriString(infoApi)
                             .queryParam("access_token", token)
                             .toUriString()
                )
            )
            .flatMap(json -> handlerInfo(json, request.getWxTemplateId()));
    }

    private static Mono<String> requestToken(WebClient webClient, String appId, String secret) {
        return WeixinGeneralRequest
            .requestToken(webClient,
                          UriComponentsBuilder
                              .fromUriString(tokenApi)
                              .queryParam("grant_type", "client_credential")
                              .queryParam("appid", appId)
                              .queryParam("secret", secret)
                              .build()
                              .toUri()
            );
    }


    private Mono<WechatTempalateDataInfo> handlerInfo(JSONObject jsonObject, String wxTemplateId) {
        return Mono.just(jsonObject.getJSONArray("template_list"))
                   .flatMapMany(Flux::fromIterable)
                   .map(o -> JSONObject.parseObject(JSONObject.toJSONString(o)))
                   .filter(json -> wxTemplateId.equals(json.getString("template_id")))
                   .next()
                   .map(json -> {
                       WechatTempalateDataInfo wechatTempalateDataInfo = new WechatTempalateDataInfo();
                       wechatTempalateDataInfo.setTitle(json.getString("title"));
                       wechatTempalateDataInfo.setContent(json.getString("content"));
                       return wechatTempalateDataInfo;
                   });
    }


    @Getter
    @Setter
    public static class WechatTempalateDataRequest {

        @NotNull
        @Schema(description = "对应配置的appId")
        private String appId;

        @NotNull
        @Schema(description = "对应配置的secret")
        private String secret;

        @NotNull
        @Schema(description = "微信模板ID")
        private String wxTemplateId;

    }

    @Getter
    @Setter
    public static class WechatTempalateDataInfo implements Serializable {

        private String title;
        private String content;

    }


}
